package com.hb.trade.api.routine.controller.center.au;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hb.core.pojo.RoleDataAuthEntity;
import com.hb.core.pojo.center.au.dto.RoleDTO;
import com.hb.core.pojo.center.au.entity.Role;
import com.hb.core.pojo.center.au.entity.User;
import com.hb.core.pojo.center.sys.dto.MenuResourceDTO;
import com.hb.core.pojo.enums.RoleDataAuthEnum;
import com.hb.core.pojo.parent.PageResult;
import com.hb.trade.api.routine.util.RoleDataAuthUtil;
import com.hb.trade.client.center.MenuResourceClient;
import com.hb.trade.client.center.RoleClient;
import com.hb.trade.client.center.UserClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.fzzn.core.auth.shiro.util.ShiroUtil;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 系统用户相关
 */
@Slf4j
@Version(1.0)
@Api(tags = {"角色管理管理"})
@RequestMapping("/{version}")
@RestController
public class ApiRoleController {

    protected final RoleClient roleClient;
    protected final UserClient userClient;
    protected final MenuResourceClient menuResourceClient;

    public ApiRoleController(RoleClient roleClient, UserClient userClient, MenuResourceClient menuResourceClient) {
        this.roleClient = roleClient;
        this.userClient = userClient;
        this.menuResourceClient = menuResourceClient;
    }

    /**
     * 角色列表, 用于新增员工时的角色下拉框
     * <p>
     * 20220419 v2.1.02 只查询当前企业下的角色列表
     * 20220421 v2.1.02 查询当前企业下的角色列表 + 分公司管理员(分公司管理员只有总公司有)
     * 20220429 v2.1.02 查询当前企业下的角色列表 + 分公司管理员(分公司作为当前登录者业务角色的角色列表)
     *
     * @param roleDTO#roleSign 该参数为非必填参数, 只能由前端传递
     * @return
     */
    @ApiOperation(value = "角色列表", notes = "角色列表信息(不分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgId", value = "企业ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "roleSign", value = "业务角色标识", dataTypeClass = Integer.class)
    })
    @PostMapping("/role/listRoles")
    public ResponseDto<?> listRoles(@RequestBody RoleDTO roleDTO) {
        Long orgId = roleDTO.getOrgId();
        if (orgId == null) {
            roleDTO.setOrgId(ShiroUtil.getOrgId());
        }
        Long userId = ShiroUtil.getUserId();
        Message<User> userMessage = userClient.getByUserId(userId);
        if (userMessage.isSuccess()) {
            User data = userMessage.getData();
            roleDTO.setAccountLevel(data.getAccountLevel());
        }
        Message<List<Role>> listRoleMsg = roleClient.listRoles(roleDTO);
        return ResultUtil.msg(listRoleMsg);
    }

    /**
     * 角色列表信息(返回分页对象)
     *
     * @return
     */
    @ApiOperation(value = "角色列表信息", notes = "用户列表信息(返回分页对象)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页数", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "每夜条数", dataTypeClass = Integer.class)
    })
    @PostMapping("/role/pageRoles")
    public ResponseDto<?> pageRoles(@RequestBody RoleDTO roleDTO) {
        // 判断当前登录用户的用户类型
        Long orgId = ShiroUtil.getOrgId();
        roleDTO.setOrgId(orgId);

        Integer roleSign = ShiroUtil.getExtInfoInt("roleSign");
        roleDTO.setRoleSign(roleSign);

        RoleDataAuthEntity dataAuth = RoleDataAuthUtil.buildDataAuth();
        roleDTO.setDataAuth(dataAuth);

        Message<PageResult<RoleDTO>> pageRoleMsg = roleClient.pageRoles(roleDTO);
        return ResultUtil.msg(pageRoleMsg);
    }

    /**
     * 查询指定角色下的用户成员列表
     *
     * @return
     */
    @ApiOperation(value = "查询指定角色下的用户成员列表", notes = "查询指定角色下的用户成员列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "pageFlag", value = "返回的数据格式(1: 分页对象, 2: 列表, 其他值: 默认分页)", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "currentPage", value = "当前页数", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataTypeClass = Integer.class)
    })
    @PostMapping("/role/membersByRole")
    public ResponseDto membersByRole(@RequestBody RoleDTO roleDTO) {
        Message<RoleDTO> roleMsg = roleClient.membersByRole(roleDTO);
        return ResultUtil.msg(roleMsg);
    }

    /**
     * 新增或更新角色信息
     *
     * @return
     */
    @ApiOperation(value = "新增或更新角色信息", notes = "新增或更新角色信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID(为空时新增数据)", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "parentId", value = "父级角色ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "roleName", value = "角色名称", dataTypeClass = String.class),
            @ApiImplicitParam(name = "roleCode", value = "角色代码(为空时自动生成)", dataTypeClass = String.class),
            @ApiImplicitParam(name = "roleSign", value = "角色标识(1: 招标人/采购人, 2: 投标人/供应商, 3: 代理机构)", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "roleDesc", value = "角色职能描述", dataTypeClass = String.class)
    })
    @PostMapping("/role/saveRole")
    public ResponseDto<?> saveRole(@RequestBody RoleDTO roleDTO) {
        Long id = roleDTO.getId();
        boolean isCreate = (id == null);

        // 新增时设置该角色所属企业
        if (isCreate) {
            roleDTO.setOrgId(ShiroUtil.getOrgId());
        }

        // 参数验证
        String paramsValid = roleDTO.paramsValid();
        if (StrUtil.isNotEmpty(paramsValid)) {
            return ResultUtil.fail(paramsValid);
        }

        // 数据权限默认为最小单位
        if (roleDTO.getRoleDataAuth() == null) {
            roleDTO.setRoleDataAuth(RoleDataAuthEnum.PERSONAL.getCode());
        }

        // 新增时roleSign参数取当前登录用户的角色
        if (isCreate) {
            // 获取当前登录用户的roleSign标识
            Long userId = ShiroUtil.getUserId();
            Message<List<RoleDTO>> listMessage = roleClient.listBiddingRoles(userId);
            if (listMessage.isSuccess()) {
                List<RoleDTO> data = listMessage.getData();
                RoleDTO one = CollUtil.findOne(data, item -> item.getRoleSign() != null);
                roleDTO.setRoleSign(one.getRoleSign());
            }
            // 必须添加createId字段, 后面数据权限查询时用
            roleDTO.setCreateId(userId);
        }

        Message<Boolean> saveRole = roleClient.saveRole(roleDTO);
        return ResultUtil.msg(saveRole);
    }

    /**
     * 删除角色
     *
     * @return
     */
    @ApiOperation(value = "删除角色", notes = "删除角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", dataTypeClass = Long.class)
    })
    @PostMapping("/role/removeRole")
    public ResponseDto removeRole(@RequestBody RoleDTO roleDTO) {
        roleDTO.setPageFlag(2);

        Message<RoleDTO> roleMsg = roleClient.membersByRole(roleDTO);
        if (roleMsg.isSuccess()) {
            RoleDTO data = roleMsg.getData();
/*            if (data.getRoleSign() != null) {
                return ResultUtil.fail("操作失败, 该角色不允许删除");
            }*/
            JSONArray array = JSONUtil.parseArray(data.getUsers());
            if (CollUtil.isEmpty(array)) {
                Message<Boolean> removeRole = roleClient.removeRole(roleDTO);
                return ResultUtil.msg(removeRole);
            }
            return ResultUtil.fail("有正在使用的用户，请移除使用后再删除");
        }
        return ResultUtil.msg(MsgEnum.FAILURE);
    }

    /**
     * 更新角色的权限
     *
     * @return
     */
    @ApiOperation(value = "更新角色的权限", notes = "更新角色的权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "resIds", value = "菜单按钮的ID集合", dataTypeClass = List.class)
    })
    @PostMapping("/role/updatePermissions")
    public ResponseDto<?> updatePermissions(@RequestBody RoleDTO roleDTO) {
        Message<Boolean> updatePermissions = roleClient.updatePermissions(roleDTO);
        return ResultUtil.msg(updatePermissions);
    }

    /**
     * 角色详情(点击编辑时回显)
     *
     * @return
     */
    @ApiOperation(value = "角色详情(点击编辑时回显)", notes = "角色详情(点击编辑时回显)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", dataTypeClass = Long.class)
    })
    @PostMapping("/role/roleDetail")
    public ResponseDto roleDetail(@RequestBody RoleDTO roleDTO) {
        Long roleDTOId = roleDTO.getId();
        if (roleDTOId == null) {
            return ResultUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        Message<RoleDTO> roleDTOMsg = roleClient.roleDetail(roleDTO);
        if (roleDTOMsg.isSuccess()) {
            MenuResourceDTO menuQuery = new MenuResourceDTO();
            menuQuery.setRoleId(roleDTOId);

            Message<List<MenuResourceDTO>> listMessage = menuResourceClient.listTrees(menuQuery);

            RoleDTO data = roleDTOMsg.getData();
            data.setMenuResources(listMessage.getData());
            return ResultUtil.msg(true, data);
        }
        return ResultUtil.msg(roleDTOMsg);
    }
}
